pub mod yb_encryptor {
    use std::error::Error;
    use anyhow::Context;
    use rsa::{PublicKey, RsaPublicKey, PaddingScheme};
    use rsa::pkcs8::FromPublicKey;
    use base64::encode;
    use crypto::aes::{cbc_encryptor, KeySize};
    use crypto::aes::KeySize::KeySize128;
    use crypto::{aes, blockmodes, buffer};
    use crypto::blockmodes::PkcsPadding;
    use crypto::buffer::{BufferResult, ReadBuffer, RefReadBuffer, RefWriteBuffer, WriteBuffer};
    use rsa::PaddingScheme::PKCS1v15Encrypt;
    use crate::client::const_variable::{AES_IV, AES_KEY};

    pub fn encrypt_password(password: &str, public_pem: &str) -> anyhow::Result<String> {
        let mut rng = rand::thread_rng();
        let padding = PaddingScheme::new_pkcs1v15_encrypt();
        let encryptor = RsaPublicKey::from_public_key_pem(public_pem)
            .with_context(|| format!("公钥格式错误!"))?;
        let data = password.as_bytes();
        let enc_data = encryptor.encrypt(&mut rng, padding, &data[..]).expect("failed to encrypt");
        Ok(encode(enc_data))
    }

    /// 加密
    /// 16, 24, or 32 字节的 key 对应 KeySize128, KeySize192, or KeySize256
    pub fn encrypt_form(key: &[u8], iv: &[u8], data: &[u8]) -> anyhow::Result<Vec<u8>> {
        let mut encryptor = aes::cbc_encryptor(
            aes::KeySize::KeySize128,
            key,
            iv,
            blockmodes::PkcsPadding);

        let mut final_result = Vec::<u8>::new();
        let mut read_buffer = buffer::RefReadBuffer::new(data);
        let mut buffer = [0; 4096];
        let mut write_buffer = buffer::RefWriteBuffer::new(&mut buffer);

        loop {
            let result = encryptor.encrypt(&mut read_buffer, &mut write_buffer, true).unwrap();

            final_result.extend(write_buffer.take_read_buffer().take_remaining().iter().map(|&i| i));

            match result {
                BufferResult::BufferUnderflow => break,
                BufferResult::BufferOverflow => {}
            }
        }

        Ok(final_result)
    }

    /// 解密
    pub fn decrypt_form(key: &[u8], iv: &[u8], text: &[u8]) -> anyhow::Result<Vec<u8>> {
        let mut decrypt = crypto::aes::cbc_decryptor(
            KeySize128,
            key,
            iv,
            PkcsPadding,
        );
        let mut read_buffer = RefReadBuffer::new(text);
        let mut result = vec![0; text.len()];
        let mut write_buffer = RefWriteBuffer::new(&mut result);
        decrypt.decrypt(&mut read_buffer, &mut write_buffer, true).unwrap();
        Ok(result)
    }
}

#[cfg(test)]
mod password_encrypted {
    use crate::encrypted::core::yb_encryptor::encrypt_password;
    use crate::encrypted::yb_encryptor::{decrypt_form, encrypt_form};

    #[test]
    fn encrypt_password_test() {
        let public_key = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4edlu8/OW8GgKBTanbv8w/1iT
KUxpIko/yGfkim2Di/XI4cgWB+fvpGqtkwMqNtcy3cr9r1oMVCLn1pqB7e3w28MW
oMnLmONnNYtE0leuYRvUu6p+SWSGzxtQSTXaV33+n3OnqCvcdXj6Dl05I20OFl84
1O65GtDG2oPOh3Bk2wIDAQAB
-----END PUBLIC KEY-----";
        let data = "L4887758258";
        let enc_str = encrypt_password(data, public_key).unwrap();
        println!("加密结果 : {}", enc_str);
    }

    #[test]
    fn decrypted_test() {
        let data_encrypted1 = b"azLKu7fUCAKmFSsLkTUOFAAdBrZmEh7Gjun9C/sDcX7x6Hp38cIedoXc0ryblHHaOSH0ixUd1RPiulQvRl7w5Olc4iQBaELqnokYOV8XPXAMBdCG+CuETfAH4bKoyo61jJ1DfIFvNMqGwp/0IVp7PLeGG9jk03f2Jmq4+Edk58KMPn++X5fTio1QmaPBmEg3IoHeeiFtBpfGUACk7CoClNtHLQpSjyF2UV0ylpPcn/B7C7vv1B0iH1qgN5XayMwX4ykLy8/RHJuuydb1KKq8IadN9xY4uNi7Pq/cQYQm8nJVIMdxD/l2hdxmnStlKGymvIWWkpFHDGyAeRzJAzWv1c+wvBlrl3JOj/75n9ubE6npCadXICBM6Ww4pX1CE8qEfon1Z68nmvQzUtgNwChIk1F7AIaBzz0HXyVrwtRxUO3Wo6QgkBQMtoSTNZl50MH5wlL6SR4ck+W80HN2vSZjWpZCs/9FL2tTgGwoOb0HyMuK8lb/5dUnBBxG+4xSXiJg5fH3P5o6K+ZWmxWaW+7s4oL0KxGRfmtSlmoeAl1etSThtRdkjogn3148fzMcVJtgHfGfp0avKV9PF2dvdyY/3A4m/WftlPA5Kdka4NS76LeZQ2lZf8B66SYeQtbd4DWYJS37N70RWA1d2R+k3kgAvjMT1mTjfIr5mH2/Z5ue6CUXqWAVcPdgvpXhp9LRdsV4EBQqaColqn5gyCMkVuxfFcBu6Wm/Fu/Xa7T5K3tQL+nePihGid+lFg6T6+lMW1h6O0nE9VmHMP/Pn1RYc84oPraiAzLd2rTCPQvtEres0I6hY2C7cRnqHtMYbB7CN80GMr723sRIwEY/Gh4reYMiVhbj9hC1WeKLdfrwX/68XjMCPnrCjdd5Kuo9UGvINMpz0SU9Fmzw/Ka0/NXC7QrgMe/qHAwBK8pKbrub8O6zjROPPS1YOdE5nbMDA+QBrP6Mi6BYGj8iVZyKHXSFnp3vxwhp+Y72UlXCv9LAaUWea5mnoEsy3anvgo3XaU3zCfdNe9TFQHuca6OH9gVa1Q2wOxfFRGSDLP1ivGrbqAZzqlRRdDTNqrxR4Klo39tKtIIOj55lRqWLjWIvPJolJC5vGAuz0Uyand8GwYdrKuBUlQw0euf8cyo6RNYJiuZE16mtZHDCuSUgbsfLz0Q4hbdzwR69X3TfW+7u0z9KH253C9cA=";
        let data_encrypted2 = b"zLKu7fUCAKmFSsLkTUOFAAdBrZmEh7Gjun9C/sDcX7x6Hp38cIedoXc0ryblHHaOSH0ixUd1RPiulQvRl7w5Olc4iQBaELqnokYOV8XPXAMBdCG+CuETfAH4bKoyo61jJ1DfIFvNMqGwp/0IVp7PLeGG9jk03f2Jmq4+Edk58KMPn++X5fTio1QmaPBmEg3IoHeeiFtBpfGUACk7CoClNtHLQpSjyF2UV0ylpPcn/B7C7vv1B0iH1qgN5XayMwX4ykLy8/RHJuuydb1KKq8IadN9xY4uNi7Pq/cQYQm8nJVIMdxD/l2hdxmnStlKGymvIWWkpFHDGyAeRzJAzWv1c+wvBlrl3JOj/75n9ubE6npCadXICBM6Ww4pX1CE8qEfon1Z68nmvQzUtgNwChIk1F7AIaBzz0HXyVrwtRxUO3Wo6QgkBQMtoSTNZl50MH5wlL6SR4ck+W80HN2vSZjWpZCs/9FL2tTgGwoOb0HyMuK8lb/5dUnBBxG+4xSXiJg5fH3P5o6K+ZWmxWaW+7s4oL0KxGRfmtSlmoeAl1etSThtRdkjogn3148fzMcVJtgHfGfp0avKV9PF2dvdyY/3A4m/WftlPA5Kdka4NS76LeZQ2lZf8B66SYeQtbd4DWYJS37N70RWA1d2R+k3kgAvjMT1mTjfIr5mH2/Z5ue6CUXqWAVcPdgvpXhp9LRdsV4EBQqaColqn5gyCMkVuxfFcBu6Wm/Fu/Xa7T5K3tQL+nePihGid+lFg6T6+lMW1h6O0nE9VmHMP/Pn1RYc84oPraiAzLd2rTCPQvtEres0I6hY2C7cRnqHtMYbB7CN80GMr723sRIwEY/Gh4reYMiVhbj9hC1WeKLdfrwX/68XjMCPnrCjdd5Kuo9UGvINMpz0SU9Fmzw/Ka0/NXC7QrgMe/qHAwBK8pKbrub8O6zjROPPS1YOdE5nbMDA+QBrP6Mi6BYGj8iVZyKHXSFnp3vxwhp+Y72UlXCv9LAaUWea5mnoEsy3anvgo3XaU3zCfdNe9TFQHuca6OH9gVa1Q2wOxfFRGSDLP1ivGrbqAZzqlRRdDTNqrxR4Klo39tKtIIOj55lRqWLjWIvPJolJC5vGAuz0Uyand8GwYdrKuBUlQw0euf8cyo6RNYJiuZE16mtZHDCuSUgbsfLz0Q4hbdzwR69X3TfW+7u0z9KH253C9cA=";
        let data_encoded = base64::decode(data_encrypted2).unwrap();
        let res = decrypt_form(b"2knV5VGRTScU7pOq", b"UmNWaNtM0PUdtFCs", &data_encoded[..])
            .unwrap();
        println!("{}", String::from_utf8(res).unwrap());
    }

    #[test]
    fn encrypted_demo() {
        let data1 = r#"{"WFId":"b7b79316f5b732610023d987ec950577","Data":"{\"a069e4b52079413679cc71a8f70c7edf\":\"正常在校\",\"98205659930dc79306b3c41ede65f239\":{\"name\":\"南京师范大学仙林校区北区学生餐厅\",\"location\":\"118.913705,32.114096\",\"address\":\"文苑路1号南师大仙林校区内\"},\"303558fbc358e7fccdb9a1e258606ffc\":[\"体温正常，身体健康（37.3°以下）\"],\"664d3c096eefcdc6f80e35b1c701a227\":\"36.6°-36.9°（正常体温）\",\"7bdcea686bff26915e91ce77034de2b3\":\"体温正常，身体健康（37.3°以下）\"}","WfprocessId":"b424f4428280af80c036a0bc9f28139e","Extend":"{\"TaskId\":\"844ae7e4aed30dbfd835847de3d2a0c2\",\"title\":\"任务信息\",\"content\":[{\"label\":\"任务名称\",\"value\":\"0907本科生健康动态日报\"},{\"label\":\"发布机构\",\"value\":\"学生工作处\"}]}","CustomProcess":"{\"ApplyPersonIds\":[],\"CCPersonId\":[]}"}"#;

        let res = encrypt_form(b"2knV5VGRTScU7pOq", b"UmNWaNtM0PUdtFCs", data1.as_bytes()).unwrap();
        println!("转换后：{}", &base64::encode(res));
    }
}